package org.ytor.core.sqlflow.dsl.expr;

import org.ytor.core.sqlflow.dsl.expr.node.ExprNode;
import org.ytor.core.sqlflow.dsl.expr.node.support.*;

public class ExprAstPrinter {

    public static void printAst(ExprNode node) {
        printAst(node, "", true);
    }

    private static void printAst(ExprNode node, String prefix, boolean isLast) {
        String connector = isLast ? "└── " : "├── ";
        System.out.print(prefix + connector);

        switch (node) {
            case BinaryOpNode bin -> {
                System.out.println("BinaryOp: " + bin.operator);
                printAst(bin.left, prefix + (isLast ? "    " : "│   "), false);
                printAst(bin.right, prefix + (isLast ? "    " : "│   "), true);
            }
//            case UnaryOpNode unary -> {
//                System.out.println("UnaryOp: " + unary.operator);
//                printAst(unary.operand, prefix + (isLast ? "    " : "│   "), true);
//            }
            case VariableNode var -> System.out.println("Variable: " + var.name);
            case LiteralNode lit -> System.out.println("Literal: " + lit.value);
            case FunctionCallNode func -> {
                System.out.println("FunctionCall: " + func.functionName);
                for (int i = 0; i < func.arguments.size(); i++) {
                    printAst(func.arguments.get(i), prefix + (isLast ? "    " : "│   "), i == func.arguments.size() - 1);
                }
            }
            case TupleNode tuple -> {
                System.out.println("Tuple:");
                for (int i = 0; i < tuple.elements.size(); i++) {
                    printAst(tuple.elements.get(i), prefix + (isLast ? "    " : "│   "), i == tuple.elements.size() - 1);
                }
            }
            case null, default -> System.out.println("Unknown: " + node.getClass().getSimpleName());
        }
    }
}
